import React, { useEffect, useRef, useState } from "react";

// 组件实例：类组件
// dom对象： 标签
// 执行useRef函数并传入null，返回值为一个对象 内部有一个current属性存放拿到的dom对象（组件实例）,等价于React.createRef
// useRef也可以进行保存变量使用
class Test extends React.Component {
    render() {
        return <div>我是test类组件</div>;
    }
}
function TestB() {
    return <div>我是test函数组件</div>;
}
function App() {
    const [count, setcount] = useState(0);

    //获取DOM节点
    const inputRef = useRef(); //也可以不传null
    const testRef = useRef(null);
    const testBRef = useRef(null);
    const h1Ref = useRef(null);

    //保存（缓存）变量
    const number = useRef(10);

    //普通变量无法缓存，每次组件更新都会重新初始化定义
    let number2 = 0;

    useEffect(() => {
        console.log("number-->", number.current);

        inputRef.current.focus();
        console.log("h1Ref-->", h1Ref.current);
        console.log("testRef-->", testRef.current);
        //不能通过ref获取函数组件，会报错
        console.log("testBRef-->", testBRef.current);
    }, []);

    return (
        <div>
            <input type='text' ref={inputRef} />
            <Test ref={testRef}></Test>
            {/* 函数组件由于没有实例，不能使用ref获取，如果想获取组件实例，必须是类组件 */}
            {/* 报错 */}
            <TestB ref={testBRef}></TestB>
            <h1 ref={h1Ref}>我是h1</h1>
            <hr />
            <button
                onClick={() => {
                    setcount(count + 1); //只有通过一定手段触发组件重新渲染，才能向页面上展示ref保存的变量的新值
                    number.current++;
                    number2++; //number2不会增加，因为每次组件重新渲染number2都会被重新定义为0
                }}>
                add
            </button>{" "}
            {number.current}--{number2}
        </div>
    );
}

export default App;

/**
 * react中具有缓存作用的功能都是通过引用js闭包实现的，如useState，useRef，useCallback等
 */
